﻿using Basic.UserModel.DB;
using Basic.UserModel.WxUser;
using WeDonekRpc.Helper;
using WeDonekRpc.Helper.IdGenerator;
using WeDonekRpc.SqlSugar;

namespace Basic.UserRepository.lmpl
{
    internal class WxUserRepository : UserBaseRepository<DBWxUser, long>, IWxUserRepository
    {
        public WxUserRepository (ISqlClientFactory factory) : base(factory)
        {
        }
        public T FindWxUser<T> (long thirdId, string openId) where T : class, new()
        {
            return base.Get<T>(a => a.ThirdId == thirdId && a.WxOpenId == openId && a.IsBind);
        }
        public long RegWxUser (WxUserBase add)
        {
            DBWxUser user = new DBWxUser
            {
                Id = IdentityHelper.CreateId(),
                WxOpenId = add.WxOpenId,
                ThirdId = add.ThirdId,
                RegTime = DateTime.Now,
                UnionId = add.UnionId
            };
            base.Insert(user);
            return user.Id;
        }
        public BindWxUser FindBindWxUser (long thirdId, long userId)
        {
            return base.Get<BindWxUser>(a => a.ThirdId == thirdId && a.BindUserId == userId && a.IsBind);
        }
        public void CancelBind (long id)
        {
            if (!base.Update(new DBWxUser
            {
                Id = id,
                IsBind = false,
                CancelTime = DateTime.Now
            },
            new string[]
            {
                "CancelTime",
                "IsBind"
             }))
            {
                throw new ErrorException("user.wx.cancel.bind.fail");
            }
        }

        public void Bind (long id, long userId)
        {
            if (!base.Update(new DBWxUser
            {
                Id = id,
                BindUserId = userId,
                BindTime = DateTime.Now,
                IsBind = true
            }, new string[]
            {
                "BindUserId",
                "BindTime",
                "IsBind"
            }))
            {
                throw new ErrorException("user.wx.bind.fail");
            }
        }
        public void Bind (long id, long userId, long cancelId)
        {
            ISqlQueue<DBWxUser> queue = base.BeginQueue();
            queue.Update(new DBWxUser
            {
                Id = id,
                BindUserId = userId,
                BindTime = DateTime.Now,
                IsBind = true
            }, new string[]
            {
                "BindUserId",
                "BindTime",
                "IsBind"
            });
            queue.Update(new DBWxUser
            {
                Id = cancelId,
                IsBind = false,
                CancelTime = DateTime.Now
            }, new string[]
            {
                 "CancelTime",
                "IsBind"
            });
            _ = queue.Submit();
        }

        public void CancelBind (long[] ids)
        {
            if (!base.Update(a => new DBWxUser
            {
                IsBind = false,
                CancelTime = DateTime.Now,
            }, a => ids.Contains(a.Id)))
            {
                throw new ErrorException("user.wx.cancel.bind.fail");
            }
        }

        public long[] FindId (long userId)
        {
            return base.Gets(a => a.IsBind && a.BindUserId == userId, a => a.Id);
        }
    }
}
